package com.fs.sys.web;

import cn.hutool.core.map.multi.Table;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.fs.common.bean.UserContextHolder;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.enhancer.TableEnhancer;
import com.fs.sys.bean.dto.AppDTO;
import com.fs.sys.bean.resp.AppUseStat;
import com.fs.sys.bean.resp.MonthCount;
import com.fs.sys.entityservice.AppEntityService;
import com.fs.sys.entityservice.AppUseLogEntityService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统计相关接口
 *
 * @author  LiuQi 2025/6/13-10:31
 * @version V1.0
 **/
@RestController
@RequestMapping("/sys/stat")
public class StatController {
    @Autowired
    private AppUseLogEntityService appUseLogEntityService;

    @Autowired
    private AppEntityService appEntityService;

    /**
     * 查询近12个月的应用访问统计情况
     */
    @GetMapping("month/app")
    public Map<String, List<AppUseStat>> appStatByMonth() {
        LocalDate startDate = LocalDate.now().withDayOfMonth(1).minusMonths(12);
        Table<String, String, AppUseStat> table = appUseLogEntityService.queryBuilder()
                .ge("create_time", startDate)
                .groupBy("app_id, date_format(create_time, '%Y/%m')")
                .select("app_id as appId, count(1) as `count`, date_format(create_time, '%Y/%m') as dataMonth")
                .queryMaps()
                .stream()
                .map(m -> {
                    AppUseStat stat = new AppUseStat();
                    stat.setCount(MapUtils.getIntValue(m, "count"));
                    stat.setDataMonth(MapUtils.getString(m, "dataMonth"));
                    stat.setAppId(MapUtils.getString(m, "appId"));
                    return stat;
                })
                .collect(TableEnhancer.collector(AppUseStat::getAppId, AppUseStat::getDataMonth));

        List<AppDTO> apps = appEntityService.findAll();

        // 按月处理并补充无数据月份
        Map<String, List<AppUseStat>> resultMap = new HashMap<>(16);

        apps.forEach(app -> {
            String appId = app.getId();
            DateUtils.monthCallBetween(startDate, LocalDate.now().withDayOfMonth(1), dataDate -> {
                String dataMonth = dataDate.format(DateTimeFormatter.ofPattern("yyyy/MM"));
                AppUseStat stat = table.get(appId, dataMonth);
                if (null == stat) {
                    stat = new AppUseStat();
                    stat.setAppId(appId);
                    stat.setDataMonth(dataMonth);
                    stat.setCount(0);
                }
                String appName = app.getName();
                stat.setAppName(appName);
                resultMap.computeIfAbsent(appName, n -> new ArrayList<>())
                        .add(stat);
            });
        });

        return resultMap;
    }

    /**
     * 查询最近12个月的登录统计数据
     * @return 最后2个月的登录统计数据
     */
    @GetMapping("month/login")
    public List<MonthCount> loginStatByMonth() {
        String tenantId = UserContextHolder.getTenantIdOrThrow();

        LocalDate startDate = LocalDate.now().withDayOfMonth(1).minusMonths(11);
        String sql = "select date_format(create_time, '%Y/%m') as data_month, count(1) as c from sys_user_login where create_time >= '"
                + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "' and tenant_id = '" + tenantId
                + "' group by date_format(create_time, '%Y/%m')";
        List<Map<String, Object>> dataList = SqlRunner.db().selectList(sql);
        Map<String, MonthCount> dataMap = dataList.stream()
                .collect(Collectors.toMap(m -> MapUtils.getString(m, "data_month"),m -> {
                    MonthCount c = new MonthCount();
                    c.setDataMonth(MapUtils.getString(m, "data_month"));
                    c.setCount(MapUtils.getIntValue(m, "c"));
                    return c;
                }));
        LocalDate nowDate = LocalDate.now();
        List<MonthCount> list = new ArrayList<>(16);
        while (!startDate.isAfter(nowDate)) {
            String dateMonth = DateTimeFormatter.ofPattern("yyyy/MM").format(startDate);
            MonthCount count = dataMap.get(dateMonth);
            if (null == count) {
                count = new MonthCount();
                count.setDataMonth(dateMonth);
                count.setCount(0);
            }
            list.add(count);

            startDate = startDate.plusMonths(1);
        }

        return list;
    }
}
